/**
 *
 * Licensed Property to China UnionPay Co., Ltd.
 * 
 * (C) Copyright of China UnionPay Co., Ltd. 2010
 *     All Rights Reserved.
 *
 * 
 * Modification History:
 * =============================================================================
 *   Author         Date          Description
 *   ------------ ---------- ---------------------------------------------------
 *   xshu       2014-05-28       MPI基本参数工具类
 * =============================================================================
 */
package cn.fengLone.pay.util.unionPay.sdk;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;

import javax.swing.Box.Filler;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

/**
 * 
 * ClassName: SDKConfig <br/>
 * Function:  <br/>
 * Date: 2016年9月9日 <br/>
 * 
 * @author wanghao
 * @version
 * @since 1.0
 */
public class SDKConfig {

   public static final String FILE_NAME = "unionPay"+File.separator+"acp_sdk.properties";


    private final static Logger logger = Logger.getLogger(SDKConfig.class);

    /** 前台请求URL. */
    private String frontRequestUrl;

    /** 后台请求URL. */
    private String backRequestUrl;

    /** 单笔查询 */
    private String singleQueryUrl;

    /** 批量查询 */
    private String batchQueryUrl;

    /** 批量交易 */
    private String batchTransUrl;

    /** 文件传输 */
    private String fileTransUrl;

    /** 签名证书路径. */
    private String signCertPath;

    /** 签名证书密码. */
    private String signCertPwd;

    /** 签名证书类型. */
    private String signCertType;

    /** 加密公钥证书路径. */
    private String encryptCertPath;

    /** 验证签名公钥证书目录. */
    private String validateCertDir;

    /** 按照商户代码读取指定签名证书目录. */
    private String signCertDir;

    /** 磁道加密证书路径. */
    private String encryptTrackCertPath;

    /** 磁道加密公钥模数. */
    private String encryptTrackKeyModulus;

    /** 磁道加密公钥指数. */
    private String encryptTrackKeyExponent;

    /** 有卡交易. */
    private String cardRequestUrl;

    /** app交易 */
    private String appRequestUrl;

    /** 证书使用模式(单证书/多证书) */
    private String singleMode;

    /*缴费相关地址*/
    private String jfFrontRequestUrl;

    private String jfBackRequestUrl;

    private String jfSingleQueryUrl;

    private String jfCardRequestUrl;

    private String jfAppRequestUrl;

    /** 配置文件中的前台URL常量. */
    public static final String SDK_FRONT_URL = "acpsdk.frontTransUrl";

    /** 配置文件中的后台URL常量. */
    public static final String SDK_BACK_URL = "acpsdk.backTransUrl";

    /** 配置文件中的单笔交易查询URL常量. */
    public static final String SDK_SIGNQ_URL = "acpsdk.singleQueryUrl";

    /** 配置文件中的批量交易查询URL常量. */
    public static final String SDK_BATQ_URL = "acpsdk.batchQueryUrl";

    /** 配置文件中的批量交易URL常量. */
    public static final String SDK_BATTRANS_URL = "acpsdk.batchTransUrl";

    /** 配置文件中的文件类交易URL常量. */
    public static final String SDK_FILETRANS_URL = "acpsdk.fileTransUrl";

    /** 配置文件中的有卡交易URL常量. */
    public static final String SDK_CARD_URL = "acpsdk.cardTransUrl";

    /** 配置文件中的app交易URL常量. */
    public static final String SDK_APP_URL = "acpsdk.appTransUrl";

    /** 以下缴费产品使用，其余产品用不到，无视即可 */
    // 前台请求地址
    public static final String JF_SDK_FRONT_TRANS_URL = "acpsdk.jfFrontTransUrl";

    // 后台请求地址
    public static final String JF_SDK_BACK_TRANS_URL = "acpsdk.jfBackTransUrl";

    // 单笔查询请求地址
    public static final String JF_SDK_SINGLE_QUERY_URL = "acpsdk.jfSingleQueryUrl";

    // 有卡交易地址
    public static final String JF_SDK_CARD_TRANS_URL = "acpsdk.jfCardTransUrl";

    // App交易地址
    public static final String JF_SDK_APP_TRANS_URL = "acpsdk.jfAppTransUrl";

    /** 配置文件中签名证书路径常量. */
    public static final String SDK_SIGNCERT_PATH = "acpsdk.signCert.path";

    /** 配置文件中签名证书密码常量. */
    public static final String SDK_SIGNCERT_PWD = "acpsdk.signCert.pwd";

    /** 配置文件中签名证书类型常量. */
    public static final String SDK_SIGNCERT_TYPE = "acpsdk.signCert.type";

    /** 配置文件中密码加密证书路径常量. */
    public static final String SDK_ENCRYPTCERT_PATH = "acpsdk.encryptCert.path";

    /** 配置文件中磁道加密证书路径常量. */
    public static final String SDK_ENCRYPTTRACKCERT_PATH = "acpsdk.encryptTrackCert.path";

    /** 配置文件中磁道加密公钥模数常量. */
    public static final String SDK_ENCRYPTTRACKKEY_MODULUS = "acpsdk.encryptTrackKey.modulus";

    /** 配置文件中磁道加密公钥指数常量. */
    public static final String SDK_ENCRYPTTRACKKEY_EXPONENT = "acpsdk.encryptTrackKey.exponent";

    /** 配置文件中验证签名证书目录常量. */
    public static final String SDK_VALIDATECERT_DIR = "acpsdk.validateCert.dir";

    /** 配置文件中是否加密cvn2常量. */
    public static final String SDK_CVN_ENC = "acpsdk.cvn2.enc";

    /** 配置文件中是否加密cvn2有效期常量. */
    public static final String SDK_DATE_ENC = "acpsdk.date.enc";

    /** 配置文件中是否加密卡号常量. */
    public static final String SDK_PAN_ENC = "acpsdk.pan.enc";

    /** 配置文件中证书使用模式 */
    public static final String SDK_SINGLEMODE = "acpsdk.singleMode";

    /** 操作对象. */
    private static SDKConfig config;

    /** 属性文件对象. */
    private Properties properties;

    /**
     * 获取config对象.
     * 
     * @return
     */
    public static SDKConfig getConfig() {
        if (null == config) {
            config = new SDKConfig();
        }
        return config;
    }

    /**
     * 从properties文件加载
     * 
     * @param rootPath
     *            不包含文件名的目录.
     */
    public void loadPropertiesFromPath(String rootPath) {
        if (StringUtils.isNotBlank(rootPath)) {
            File file = new File(rootPath + File.separator + FILE_NAME);
            System.out.println(file.getPath());
            InputStream in = null;
            if (file.exists()) {
                try {
                    in = new FileInputStream(file);
                    BufferedReader bf = new BufferedReader(new InputStreamReader(in, "utf-8"));
                    properties = new Properties();
                    properties.load(bf);
                    loadProperties(properties);
                } catch (FileNotFoundException e) {
                    LogUtil.writeErrorLog(e.getMessage(), e);
                } catch (IOException e) {
                    LogUtil.writeErrorLog(e.getMessage(), e);
                } finally {
                    if (null != in) {
                        try {
                            in.close();
                        } catch (IOException e) {
                            LogUtil.writeErrorLog(e.getMessage(), e);
                        }
                    }
                }
            } else {
                // 由于此时可能还没有完成LOG的加载，因此采用标准输出来打印日志信息
                System.out.println(rootPath + FILE_NAME + "不存在,加载参数失败");
            }
        } else {
            loadPropertiesFromSrc();
        }

    }

    /**
     * 从classpath路径下加载配置参数
     */
    public void loadPropertiesFromSrc() {
        InputStream in = null;
        try {
            // Properties pro = null;
            logger.info("从classpath: " + SDKConfig.class.getClassLoader().getResource("").getPath() + " 获取属性文件"
                    + FILE_NAME);
            in = SDKConfig.class.getClassLoader().getResourceAsStream(FILE_NAME);
            if (null != in) {
                BufferedReader bf = new BufferedReader(new InputStreamReader(in, "utf-8"));
                properties = new Properties();
                try {
                    properties.load(bf);
                } catch (IOException e) {
                    throw e;
                }
            } else {
                LogUtil.writeErrorLog(FILE_NAME + "属性文件未能在classpath指定的目录下 "
                        + SDKConfig.class.getClassLoader().getResource("").getPath() + " 找到!");
                return;
            }
            loadProperties(properties);
        } catch (IOException e) {
            LogUtil.writeErrorLog(e.getMessage(), e);
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    LogUtil.writeErrorLog(e.getMessage(), e);
                }
            }
        }
    }

    /**
     * 根据传入的 {@link #load(java.util.Properties)}对象设置配置参数
     * 
     * @param pro
     */
    public void loadProperties(Properties pro) {
        logger.info("开始从属性文件中加载配置项");
        String value = null;
        value = pro.getProperty(SDK_SINGLEMODE);
        if (SDKUtil.isEmpty(value) || SDKConstants.TRUE_STRING.equals(value)) {
            this.singleMode = SDKConstants.TRUE_STRING;
            logger.info("单证书模式，使用配置文件配置的私钥签名证书，SingleCertMode:[" + this.singleMode + "]");
            // 单证书模式
            value = pro.getProperty(SDK_SIGNCERT_PATH);
            //String pa="/src/main/resources/certs/acp_test_sign.pfx";
            //value = System.getProperty("user.dir")+pa;

            if (!SDKUtil.isEmpty(value)) {
                this.signCertPath = value.trim();
                logger.info("配置项：私钥签名证书路径==>" + SDK_SIGNCERT_PATH + "==>" + value + " 已加载");
            }
            value = pro.getProperty(SDK_SIGNCERT_PWD);
            if (!SDKUtil.isEmpty(value)) {
                this.signCertPwd = value.trim();
                logger.info("配置项：私钥签名证书密码==>" + SDK_SIGNCERT_PWD + " 已加载");
            }
            value = pro.getProperty(SDK_SIGNCERT_TYPE);
            if (!SDKUtil.isEmpty(value)) {
                this.signCertType = value.trim();
                logger.info("配置项：私钥签名证书类型==>" + SDK_SIGNCERT_TYPE + "==>" + value + " 已加载");
            }
        } else {
            // 多证书模式
            this.singleMode = SDKConstants.FALSE_STRING;
            logger.info("多证书模式，不需要加载配置文件中配置的私钥签名证书，SingleMode:[" + this.singleMode + "]");
        }
        value = pro.getProperty(SDK_ENCRYPTCERT_PATH);
        if (!SDKUtil.isEmpty(value)) {
            this.encryptCertPath = value.trim();
            logger.info("配置项：敏感信息加密证书==>" + SDK_ENCRYPTCERT_PATH + "==>" + value + " 已加载");
        }
        value = pro.getProperty(SDK_VALIDATECERT_DIR);
        if (!SDKUtil.isEmpty(value)) {
            this.validateCertDir = value.trim();
            logger.info("配置项：验证签名证书路径(这里配置的是目录，不要指定到公钥文件)==>" + SDK_VALIDATECERT_DIR + "==>" + value + " 已加载");
        }
        value = pro.getProperty(SDK_FRONT_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.frontRequestUrl = value.trim();
        }
        value = pro.getProperty(SDK_BACK_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.backRequestUrl = value.trim();
        }
        value = pro.getProperty(SDK_BATQ_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.batchQueryUrl = value.trim();
        }
        value = pro.getProperty(SDK_BATTRANS_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.batchTransUrl = value.trim();
        }
        value = pro.getProperty(SDK_FILETRANS_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.fileTransUrl = value.trim();
        }
        value = pro.getProperty(SDK_SIGNQ_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.singleQueryUrl = value.trim();
        }
        value = pro.getProperty(SDK_CARD_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.cardRequestUrl = value.trim();
        }
        value = pro.getProperty(SDK_APP_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.appRequestUrl = value.trim();
        }
        value = pro.getProperty(SDK_ENCRYPTTRACKCERT_PATH);
        if (!SDKUtil.isEmpty(value)) {
            this.encryptTrackCertPath = value.trim();
        }

        /**缴费部分**/
        value = pro.getProperty(JF_SDK_FRONT_TRANS_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.jfFrontRequestUrl = value.trim();
        }

        value = pro.getProperty(JF_SDK_BACK_TRANS_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.jfBackRequestUrl = value.trim();
        }

        value = pro.getProperty(JF_SDK_SINGLE_QUERY_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.jfSingleQueryUrl = value.trim();
        }

        value = pro.getProperty(JF_SDK_CARD_TRANS_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.jfCardRequestUrl = value.trim();
        }

        value = pro.getProperty(JF_SDK_APP_TRANS_URL);
        if (!SDKUtil.isEmpty(value)) {
            this.jfAppRequestUrl = value.trim();
        }

        value = pro.getProperty(SDK_ENCRYPTTRACKKEY_EXPONENT);
        if (!SDKUtil.isEmpty(value)) {
            this.encryptTrackKeyExponent = value.trim();
        }

        value = pro.getProperty(SDK_ENCRYPTTRACKKEY_MODULUS);
        if (!SDKUtil.isEmpty(value)) {
            this.encryptTrackKeyModulus = value.trim();
        }
    }

    public String getFrontRequestUrl() {
        return frontRequestUrl;
    }

    public void setFrontRequestUrl(String frontRequestUrl) {
        this.frontRequestUrl = frontRequestUrl;
    }

    public String getBackRequestUrl() {
        return backRequestUrl;
    }

    public void setBackRequestUrl(String backRequestUrl) {
        this.backRequestUrl = backRequestUrl;
    }

    public String getSignCertPath() {
        return signCertPath;
    }

    public void setSignCertPath(String signCertPath) {
        this.signCertPath = signCertPath;
    }

    public String getSignCertPwd() {
        return signCertPwd;
    }

    public void setSignCertPwd(String signCertPwd) {
        this.signCertPwd = signCertPwd;
    }

    public String getSignCertType() {
        return signCertType;
    }

    public void setSignCertType(String signCertType) {
        this.signCertType = signCertType;
    }

    public String getEncryptCertPath() {
        return encryptCertPath;
    }

    public void setEncryptCertPath(String encryptCertPath) {
        this.encryptCertPath = encryptCertPath;
    }

    public String getValidateCertDir() {
        return validateCertDir;
    }

    public void setValidateCertDir(String validateCertDir) {
        this.validateCertDir = validateCertDir;
    }

    public String getSingleQueryUrl() {
        return singleQueryUrl;
    }

    public void setSingleQueryUrl(String singleQueryUrl) {
        this.singleQueryUrl = singleQueryUrl;
    }

    public String getBatchQueryUrl() {
        return batchQueryUrl;
    }

    public void setBatchQueryUrl(String batchQueryUrl) {
        this.batchQueryUrl = batchQueryUrl;
    }

    public String getBatchTransUrl() {
        return batchTransUrl;
    }

    public void setBatchTransUrl(String batchTransUrl) {
        this.batchTransUrl = batchTransUrl;
    }

    public String getFileTransUrl() {
        return fileTransUrl;
    }

    public void setFileTransUrl(String fileTransUrl) {
        this.fileTransUrl = fileTransUrl;
    }

    public String getSignCertDir() {
        return signCertDir;
    }

    public void setSignCertDir(String signCertDir) {
        this.signCertDir = signCertDir;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public String getCardRequestUrl() {
        return cardRequestUrl;
    }

    public void setCardRequestUrl(String cardRequestUrl) {
        this.cardRequestUrl = cardRequestUrl;
    }

    public String getAppRequestUrl() {
        return appRequestUrl;
    }

    public void setAppRequestUrl(String appRequestUrl) {
        this.appRequestUrl = appRequestUrl;
    }

    public String getEncryptTrackCertPath() {
        return encryptTrackCertPath;
    }

    public void setEncryptTrackCertPath(String encryptTrackCertPath) {
        this.encryptTrackCertPath = encryptTrackCertPath;
    }

    public String getJfFrontRequestUrl() {
        return jfFrontRequestUrl;
    }

    public void setJfFrontRequestUrl(String jfFrontRequestUrl) {
        this.jfFrontRequestUrl = jfFrontRequestUrl;
    }

    public String getJfBackRequestUrl() {
        return jfBackRequestUrl;
    }

    public void setJfBackRequestUrl(String jfBackRequestUrl) {
        this.jfBackRequestUrl = jfBackRequestUrl;
    }

    public String getJfSingleQueryUrl() {
        return jfSingleQueryUrl;
    }

    public void setJfSingleQueryUrl(String jfSingleQueryUrl) {
        this.jfSingleQueryUrl = jfSingleQueryUrl;
    }

    public String getJfCardRequestUrl() {
        return jfCardRequestUrl;
    }

    public void setJfCardRequestUrl(String jfCardRequestUrl) {
        this.jfCardRequestUrl = jfCardRequestUrl;
    }

    public String getJfAppRequestUrl() {
        return jfAppRequestUrl;
    }

    public void setJfAppRequestUrl(String jfAppRequestUrl) {
        this.jfAppRequestUrl = jfAppRequestUrl;
    }

    public String getSingleMode() {
        return singleMode;
    }

    public void setSingleMode(String singleMode) {
        this.singleMode = singleMode;
    }

    public SDKConfig() {
        super();
    }

    public String getEncryptTrackKeyExponent() {
        return encryptTrackKeyExponent;
    }

    public void setEncryptTrackKeyExponent(String encryptTrackKeyExponent) {
        this.encryptTrackKeyExponent = encryptTrackKeyExponent;
    }

    public String getEncryptTrackKeyModulus() {
        return encryptTrackKeyModulus;
    }

    public void setEncryptTrackKeyModulus(String encryptTrackKeyModulus) {
        this.encryptTrackKeyModulus = encryptTrackKeyModulus;
    }

}
